package com.ems.util;

import org.apache.commons.lang3.StringUtils;

/**
 * 数据采集分析工具
 */
public class HexUtil {


    /**
     * 十进制数转两字节byte数组
     * @param hex
     * @return
     */
    public static byte[] hexToTwoBytes (String hex) {
        int num = Integer.parseInt ( hex );
        byte[] bytes = new byte[2];
        for ( int i = 0; i < 2; i++ ) {
            bytes[1 - i] = (byte) ( ( num >> ( i * 8 ) ) & 0xFF );
        }
        return bytes;
    }

    /**
     * 十进制数转四字节byte数组
     * @param hex
     * @return
     */
    public static byte[] hexStringToByteArray (String hex) {
        System.out.println (hex);
        int len = hex.length ();
        // 如果不足8位，高位补0
        while ( len < 8 ) {
            System.out.println ("-----11");
            hex = "0" + hex;
            len++;
        }
        System.out.println (hex);
        System.out.println (len);
        byte[] data = new byte[len / 2];
        for ( int i = 0; i < len; i += 2 ) {
            data[i / 2] = (byte) ( ( Character.digit ( hex.charAt ( i ), 16 ) << 4 ) + Character.digit ( hex.charAt ( i + 1 ), 16 ) );
        }
        return data;
    }


    /**
     * 1.字节转成十六进制，获得采集器传来的所有数据
     * @param bytes
     * @return
     */
    public static String bytesToHexString (byte[] bytes) {
        StringBuilder sb = new StringBuilder ();
        for ( int i = 0; i < bytes.length; i++ ) {
            String hex = Integer.toHexString ( 0xFF & bytes[i] );
            if ( hex.length () == 1 ) {
                sb.append ( '0' );
            }
            sb.append ( hex );
        }
        return sb.toString ();
    }

    /**
     * 通过字符串和指定长度截取子字符串
     * @param data:                      02 00 00 00 01 2f 84 00 01 00 01 04 28
     * @param index:开始截取的字节所在的下标，每个字节占两位
     * @param length：截取的字节长度
     * @return：返回截取成功后的子串
     */
    public static String parseData (String data, int index, int length) {
        if ( StringUtils.isBlank ( data ) ) {
            return null;
        }
        if ( data.length () < length ) {
            return null;
        }
        data = data.replace ( " ", "" ).trim ();
        String value = StringUtils.substring ( data, index * 2, index * 2 + length * 2 );
        return value;
    }

    /**
     * 根据给定的十六进制求截取某一部分字节，将其转为十进制
     * @param: 0c 00 0c 05 1a 0c 01 66 73 6a 79 23 25 40 32 30 31 36 15 0d
     * @param: start 开始截取的字节所在下标，每个字节占两个bit，从0开始，故每次起始下标乘以2
     * @param: length 截取的长度 0 表示不截取，每个字节占两个bit，故长度乘以2
     * @return: int，返回的十进制数据
     * @description: 按位计算，位值乘权重
     */
    public static int hexToDecimal (String hex, int start, int length) {
        hex = hex.replace ( " ", "" ).trim ().toUpperCase ();
        if ( length <= 0 ) {
            return 0;
        }
        hex = hex.substring ( start * 2, start * 2 + length * 2 );
        int outcome = 0;
        for ( int i = 0; i < hex.length (); i++ ) {
            char hexChar = hex.charAt ( i );
            outcome = outcome * 16 + charToDecimal ( hexChar );
        }
        return outcome;
    }

    /**
     * @param: [c]
     * @return: int
     * @description:将字符转化为数字
     */
    private static int charToDecimal (char c) {
        if ( c >= 'A' && c <= 'F' )
            return 10 + c - 'A';
        else
            return c - '0';
    }


    /**
     * 十进制数扩大multiple倍率数倍后，转length位十六进制Bin码
     * 处理高低位互换
     * @param value：十进制数                                1.51
     * @param multiple：小数倍率，要保留或要扩大的位数，如果value是整数时，该值为1
     * @param length：要转的bin码字节数
     * @return
     */
    public static String decimalToBinCode (String value, int multiple, int length) {
        String expand = CommonUtil.expand ( value, multiple );//1.51->151
        String hexString = stringToHex ( expand, length );//151->00000097
        String result = highLowSwap ( hexString );//97000000
        return result;
    }


    /**
     * Bin码转缩小multiple倍率数倍后，转十进制数
     * @param value：充电桩给的Bin码
     * @param multiple：要缩小的倍率，倍数，如果value是整数，该值为1
     * @param pointer：小数点后位数，如果Bin码要转的是十进制整数，该值为0
     * @return
     */
    public static String binCodeToDecimal (String value, int multiple, int pointer) {
        String swap = highLowSwap ( value ); //e0930400->000493e0
        int decimal = Integer.parseInt ( swap, 16 ); //000493e0->300000 / 10000
        String result = CommonUtil.parseDecimalPoint ( decimal, multiple, pointer );
        return result;
    }

    /**
     * 4字节十进制数据转八位十六进制数据
     * @param value：十进制整数
     * @param length：十六进制位数，四字节则是八位
     * @return：八位十六进制数据，不足八位补0
     */
    private static String stringToHex (String value, int length) {
        int iValue = Integer.parseInt ( value );
        String sValue = Integer.toHexString ( iValue );
        // 如果不足八位前面补0
        while ( sValue.length () < length ) {
            sValue = "0".concat ( sValue );
        }
        return sValue;
    }

    /**
     * 十六进制的高低位调换
     * @param hexString
     * @return
     */
    private static String highLowSwap (String hexString) {
        hexString = hexString.replace ( " ", "" ).trim ();
        int length = hexString.length ();
        int start = 0;
        int end = 2;
        StringBuilder stringBuilder = new StringBuilder ();
        for ( int i = 0; i < length / 2; i++ ) {
            // 取两位为一个字节
            String substring = hexString.substring ( start, end );
            start += 2;
            end += 2;
            stringBuilder.insert ( 0, substring );
        }
        return stringBuilder.toString ();
    }


    /**
     * Long类型的整数转十六进制，不足十六位前面补0
     * @param value：要转换十六进制的Long类型数据，不超过9223372036854775807
     * @param length：要转换成多少位的十六进制
     * @return
     */
    public static String longToHexString (String value, int length) {
        Long lValue = Long.valueOf ( value );
        StringBuilder stringBuilder = new StringBuilder ();
        while ( lValue > 0 ) {
            long remainder = lValue % 16;
            if ( remainder < 10 ) {
                stringBuilder.insert ( 0, remainder );
            } else {
                stringBuilder.insert ( 0, (char) ( 'A' + remainder - 10 ) );
            }
            lValue = lValue / 16;
        }
        while ( stringBuilder.toString ().length () < length ) {
            stringBuilder.insert ( 0, "0" );
        }
        return stringBuilder.toString ();
    }


    /**
     * 十六进制转成utf-8
     * @param hex
     * @return
     */
    public static String hexToUtf8 (String hex) {
        hex = hex.replace ( " ", "" );
        StringBuilder builder = new StringBuilder ();
        for ( int i = 0; i < hex.length (); i += 2 ) {
            String substring = hex.substring ( i, i + 2 );
            int codePoint = Integer.parseInt ( substring, 16 );
            builder.appendCodePoint ( codePoint );
        }
        String result = builder.toString ().trim ();
        return result;
    }


}
